﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Markup;

namespace Triples {

    public class AnimatablePanel : Panel {

        public static readonly DependencyProperty StartingArrangeProperty =
            DependencyProperty.RegisterAttached("StartingArrange", typeof(Rect),
            typeof(AnimatablePanel), new PropertyMetadata(default(Rect)));

        public static readonly DependencyProperty FinalArrangeProperty =
            DependencyProperty.RegisterAttached("FinalArrange", typeof(Rect),
            typeof(AnimatablePanel), new PropertyMetadata(default(Rect)));

        public static readonly DependencyProperty ArrangeProgressProperty =
            DependencyProperty.RegisterAttached("ArrangeProgress", typeof(double),
            typeof(AnimatablePanel), new PropertyMetadata(0.0, OnInvalidateArrange));


        private static void OnInvalidateArrange(DependencyObject sender, DependencyPropertyChangedEventArgs args) {
            if (sender is UIElement) (sender as UIElement).InvalidateArrange();
        }


        private static void SetStartingArrange(UIElement element, Rect value) {
            element.SetValue(StartingArrangeProperty, value);
        }

        private static void SetFinalArrange(UIElement element, Rect value) {
            element.SetValue(FinalArrangeProperty, value);
        }

        public static void SetArrangeProgress(UIElement element, double value) {
            element.SetValue(ArrangeProgressProperty, value);
        }

        private static Rect GetStartingArrange(UIElement element) {
            return (Rect)element.GetValue(StartingArrangeProperty);
        }

        private static Rect GetFinalArrange(UIElement element) {
            return (Rect)element.GetValue(FinalArrangeProperty);
        }

        public static double GetArrangeProgress(UIElement element) {
            return (double)element.GetValue(ArrangeProgressProperty);
        }

        public AnimatablePanel() {
        }


        protected override Size MeasureOverride(Size availableSize) {
            return base.MeasureOverride(availableSize);
        }


        protected override Size ArrangeOverride(Size finalSize) {

            foreach (UIElement child in Children) {
                Rect arrangement = GetCurrentArrange(child);
                child.Arrange(arrangement);
            }

            return base.ArrangeOverride(finalSize);
        }


        protected void AnimatedArrange(UIElement child, Rect rect) {
            //Rect start = GetCurrentArrange(child);
            
            //SetStartingArrange(child, start);
            SetFinalArrange(child, rect);
            //SetArrangeProgress(child, 0);
        }


        private Rect GetCurrentArrange(UIElement child) {
            Rect start = GetStartingArrange(child);
            Rect end = GetFinalArrange(child);
            double progress = GetArrangeProgress (child);

            return new Rect(
                GetProgress (start.Left, end.Left, progress),
                GetProgress(start.Top, end.Top, progress),
                end.Width,//GetProgress(start.Width, end.Width, progress),
                end.Height//GetProgress(start.Height, end.Height, progress)
                );
        }


        private static double GetProgress (double start, double end, double percentage) {
            return (end - start)*percentage + start;
        }
    }
}
